package com.maixun.lib_choosefile.ui

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.database.Cursor
import android.os.AsyncTask
import android.os.Bundle
import android.provider.MediaStore
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.maixun.lib_choosefile.LocalFileConst
import com.maixun.lib_choosefile.R
import com.maixun.lib_choosefile.adapter.LocalFileAdapter
import com.maixun.lib_choosefile.entity.FileType
import com.maixun.lib_choosefile.entity.LocalFileIm
import kotlinx.android.synthetic.main.local_file_fragment_picture.*
import java.io.File

/**
 * @author：Lmoumou
 * @date：2020/9/30
 */
class LocalFileFragment private constructor() : Fragment() {
    companion object {
        fun newInstance(type: Int): Fragment = LocalFileFragment().apply {
            val bundle = Bundle()
            bundle.putInt(LocalFileConst.FILE_TYPE, type)
            this.arguments = bundle
        }


    }

    private var first = MediaStore.Images.ImageColumns.DISPLAY_NAME
    private var second = MediaStore.Images.ImageColumns.DATA
    private var third = MediaStore.Images.ImageColumns.SIZE
    private var forth = MediaStore.Images.ImageColumns.DATE_MODIFIED

    private lateinit var mContext: Context
    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.mContext = context
    }

    private lateinit var activity: LocalFileActivity
    override fun onAttach(activity: Activity) {
        super.onAttach(activity)
        if (activity is LocalFileActivity) {
            this.activity = activity
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.local_file_fragment_picture, container, false)
    }

    private val type by lazy { arguments?.getInt(LocalFileConst.FILE_TYPE) ?: LocalFileConst.IMAGE }
    private val dataList by lazy { mutableListOf<LocalFileIm>() }
    private val adapter by lazy {
        LocalFileAdapter(mContext, type, dataList) { item, selectView, _ ->
            if (item.isSelect) {
                item.isSelect = false
                activity.dealWithItem(item)
                selectView.isSelected = item.isSelect
            } else {
                if (activity.canSelect()) {
                    item.isSelect = true
                    activity.dealWithItem(item)
                    selectView.isSelected = item.isSelect
                } else {
                    Toast.makeText(mContext, "最多可选择${activity.maxNum}个文件", Toast.LENGTH_SHORT)
                        .show()
                }
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mRecyclerView.layoutManager = if (type == LocalFileConst.IMAGE)
            GridLayoutManager(mContext, 3)
        else
            LinearLayoutManager(mContext)
        mRecyclerView.adapter = adapter
        loadData()
    }

    private fun loadData() {
        val contentResolver = mContext.contentResolver
        val cursor: Cursor = when (type) {
            LocalFileConst.VIDEO -> {
                first = MediaStore.Video.VideoColumns.DISPLAY_NAME
                second = MediaStore.Video.VideoColumns.DATA
                third = MediaStore.Video.VideoColumns.SIZE
                forth = MediaStore.Video.VideoColumns.DATE_MODIFIED
                val projection = arrayOf(first, second, third, forth)
                val selection = (MediaStore.Audio.AudioColumns.MIME_TYPE + "= ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? ")

                val selectionArgs = arrayOf(
                    "video/quicktime",
                    "video/mp4",
                    "application/vnd.rn-realmedia",
                    "aapplication/vnd.rn-realmedia",
                    "video/x-ms-wmv",
                    "video/x-msvideo",
                    "video/3gpp",
                    "video/x-matroska"
                )
                contentResolver.query(
                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection,
                    selection, selectionArgs, MediaStore.Video.VideoColumns.DATE_MODIFIED + " desc "
                )!!
            }
            LocalFileConst.AUDIO -> {
                first = MediaStore.Audio.AudioColumns.DISPLAY_NAME
                second = MediaStore.Audio.AudioColumns.DATA
                third = MediaStore.Audio.AudioColumns.SIZE
                forth = MediaStore.Audio.AudioColumns.DATE_MODIFIED
                val projection = arrayOf(first, second, third, forth)
                val selection = (MediaStore.Audio.AudioColumns.MIME_TYPE + "= ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Audio.AudioColumns.MIME_TYPE + " = ? ")

                val selectionArgs = arrayOf(
                    "audio/mpeg", "audio/x-ms-wma", "audio/x-wav", "audio/midi"
                )
                contentResolver.query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    projection,
                    selection,
                    selectionArgs,
                    MediaStore.Audio.AudioColumns.DATE_MODIFIED + " desc "
                )!!
            }
            LocalFileConst.IMAGE -> {
                first = MediaStore.Images.ImageColumns.DISPLAY_NAME
                second = MediaStore.Images.ImageColumns.DATA
                third = MediaStore.Images.ImageColumns.SIZE
                forth = MediaStore.Images.ImageColumns.DATE_MODIFIED
                val imageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                val projection = arrayOf(first, second, third, forth)
                contentResolver.query(imageUri, projection, null, null, "$forth desc ")!!
            }
            LocalFileConst.DOCUMENT -> {
                first = MediaStore.Files.FileColumns.DISPLAY_NAME
                second = MediaStore.Files.FileColumns.DATA
                third = MediaStore.Files.FileColumns.SIZE
                forth = MediaStore.Files.FileColumns.DATE_MODIFIED
                val projection = arrayOf(first, second, third, forth)

                //分别对应 txt doc pdf ppt xls wps docx pptx xlsx 类型的文档
                val selection = (MediaStore.Files.FileColumns.MIME_TYPE + "= ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? ")

                val selectionArgs = arrayOf(
                    "text/plain",
                    "application/msword",
                    "application/pdf",
                    "application/vnd.ms-powerpoint",
                    "application/vnd.ms-excel",
                    "application/vnd.ms-works",
                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                    "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                )
                contentResolver.query(
                    MediaStore.Files.getContentUri("external"), projection,
                    selection, selectionArgs, MediaStore.Files.FileColumns.DATE_MODIFIED + " desc"
                )!!
            }
            LocalFileConst.OTHER -> {
                first = MediaStore.Files.FileColumns.DISPLAY_NAME
                second = MediaStore.Files.FileColumns.DATA
                third = MediaStore.Files.FileColumns.SIZE
                forth = MediaStore.Files.FileColumns.DATE_MODIFIED
                val projection = arrayOf(first, second, third, forth)

                //分别对应 txt doc pdf ppt xls wps docx pptx xlsx 类型的文档
                val selection = (MediaStore.Files.FileColumns.MIME_TYPE + "= ? "
                        + " or " + MediaStore.Files.FileColumns.MIME_TYPE + " = ? ")
                val selectionArgs = arrayOf("text/plain", "application/zip")
                contentResolver.query(
                    MediaStore.Files.getContentUri("external"), projection,
                    selection, selectionArgs, MediaStore.Files.FileColumns.DATE_MODIFIED + " desc"
                )!!
            }
            else -> {
                throw IndexOutOfBoundsException("未知类型")
            }
        }
        AsyncData().apply {
            this.execute(cursor)
        }
    }


    @SuppressLint("StaticFieldLeak")
    inner class AsyncData : AsyncTask<Cursor, Int, MutableList<LocalFileIm>>() {
        override fun onPreExecute() {
            super.onPreExecute()
        }

        override fun doInBackground(vararg params: Cursor?): MutableList<LocalFileIm>? {
            val cursor = params[0] ?: return null
            dataList.clear()
            while (cursor.moveToNext()) {
                var name = cursor.getString(cursor.getColumnIndex(first))
                val path = cursor.getString(cursor.getColumnIndex(second))
                val size = cursor.getLong(cursor.getColumnIndex(third))
                val date = cursor.getLong(cursor.getColumnIndex(forth))
                name = name ?: path.substring(path.lastIndexOf("/") + 1, path.length)
                if (scannerFile(path) && !name.startsWith(".")) {
                    val localFileIm = LocalFileIm()
                    localFileIm.name = if (TextUtils.isEmpty(name)) path.substring(
                        path.lastIndexOf("/") + 1,
                        path.length
                    ) else name
                    localFileIm.path = path
                    localFileIm.fileSize = size
                    localFileIm.lastModifyTime = date * 1000
                    localFileIm.isData = true
                    localFileIm.type =
                        when (type) {
                            LocalFileConst.AUDIO -> FileType.AUDIO
                            LocalFileConst.VIDEO -> FileType.VIDEO
                            LocalFileConst.IMAGE -> FileType.IMAGE
                            LocalFileConst.DOCUMENT -> FileType.DOCUMENT
                            LocalFileConst.OTHER -> FileType.OTHER
                            else -> {
                                FileType.DEFAULT
                            }
                        }
                    dataList.add(localFileIm)
                }
            }

            return dataList
        }

        override fun onPostExecute(result: MutableList<LocalFileIm>?) {
            super.onPostExecute(result)
            if (dataList.isNotEmpty()) {
                adapter.notifyDataSetChanged()
                tvEmpty.visibility = View.GONE
                mRecyclerView.visibility = View.VISIBLE
            } else {
                tvEmpty.visibility = View.VISIBLE
                mRecyclerView.visibility = View.GONE
            }
        }

        private fun scannerFile(path: String): Boolean {
            val file = File(path)
            if (file.exists() && file.length() > 0) {
                if (type == LocalFileConst.DOCUMENT) {
                    val name = file.name
                    return (name.endsWith(".docx") || name.endsWith(".doc")
                            || name.endsWith(".xlsx") || name.endsWith(".xls")
                            || name.endsWith(".ppt") || name.endsWith(".pptx")
                            || name.endsWith(".pdf"))
                }
                return true
            }
            return false
        }
    }
}